﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace  BST250301TestStand.Views 
    {
        public partial class TachometerControl : Control
        {
            #region --- 属性 ---

            private float _value = 0.0f;
            [Category("Tachometer"), Description("当前转速值")]
            public float Value
            {
                get => _value;
                set
                {
                    _value = Math.Max(_minimum, Math.Min(_maximum, value));
                    this.Invalidate(); // 值改变时，重绘控件
                }
            }

            private float _minimum = 0.0f;
            [Category("Tachometer"), Description("转速表的最小值")]
            public float Minimum
            {
                get => _minimum;
                set
                {
                    _minimum = value;
                    this.Invalidate();
                }
            }

            private float _maximum = 10.0f; // 对应图中的 '10'，表示 10 * 1000 RPM
            [Category("Tachometer"), Description("转速表的最大值 (X1000 RPM)")]
            public float Maximum
            {
                get => _maximum;
                set
                {
                    _maximum = value;
                    this.Invalidate();
                }
            }

            private string _unitText = "X1000\nRPM";
            [Category("Tachometer"), Description("表盘中央的单位文本")]
            public string UnitText
            {
                get => _unitText;
                set
                {
                    _unitText = value;
                    this.Invalidate();
                }
            }

            private Color _pointerColor = Color.OrangeRed;
            [Category("Tachometer"), Description("指针的颜色")]
            public Color PointerColor
            {
                get => _pointerColor;
                set
                {
                    _pointerColor = value;
                    this.Invalidate();
                }
            }

            private Color _scaleColor = Color.White;
            [Category("Tachometer"), Description("刻度线和数字的颜色")]
            public Color ScaleColor
            {
                get => _scaleColor;
                set
                {
                    _scaleColor = value;
                    this.Invalidate();
                }
            }

            #endregion

            public TachometerControl()
            {
                this.Size = new Size(200, 200); // 默认大小
                this.BackColor = Color.Black;   // 默认背景色
                this.ForeColor = Color.White;   // 默认前景色（用于文本）

                // 启用双缓冲，防止绘图时闪烁
                this.SetStyle(ControlStyles.UserPaint |
                              ControlStyles.AllPaintingInWmPaint |
                              ControlStyles.OptimizedDoubleBuffer |
                              ControlStyles.ResizeRedraw, true);
            }

            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);

                Graphics g = e.Graphics;
                g.SmoothingMode = SmoothingMode.AntiAlias; // 抗锯齿
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; // 文本抗锯齿

                // 确定绘图区域的中心和半径
                int centerX = Width / 2;
                int centerY = Height / 2;
                int radius = Math.Min(Width, Height) / 2 - 10; // 留出一点边距

                RectangleF dialRect = new RectangleF(centerX - radius, centerY - radius, radius * 2, radius * 2);

                // 1. 绘制背景圆盘 (已经由 BackColor 属性控制)
                // g.FillEllipse(new SolidBrush(this.BackColor), dialRect);

                // 2. 绘制刻度线和数字
                using (var scalePen = new Pen(this.ScaleColor, 1.5f))
                using (var scaleBrush = new SolidBrush(this.ScaleColor))
                using (var font = new Font(this.Font.FontFamily, 10, FontStyle.Bold)) // 数字标签字体
                using (var unitFont = new Font(this.Font.FontFamily, 8, FontStyle.Regular)) // 单位文本字体
                {
                    // 角度范围：从 225 度 (左下) 到 -45 度 (右上), 总共 270 度
                    float startAngle = 225;
                    float sweepAngle = 270;

                    // 绘制主刻度线和数字
                    for (float i = _minimum; i <= _maximum; i += 1.0f) // 每隔1个单位一个主刻度
                    {
                        float angle = startAngle + (i / (_maximum - _minimum)) * sweepAngle;

                        // 将角度转换为弧度
                        float angleRad = (float)(angle * Math.PI / 180);

                        // 刻度线起点
                        float x1 = centerX + (float)((radius - 10) * Math.Cos(angleRad));
                        float y1 = centerY + (float)((radius - 10) * Math.Sin(angleRad));

                        // 刻度线终点
                        float x2 = centerX + (float)(radius * Math.Cos(angleRad));
                        float y2 = centerY + (float)(radius * Math.Sin(angleRad));
                        g.DrawLine(scalePen, x1, y1, x2, y2);

                        // 绘制数字标签
                        string text = i.ToString();
                        SizeF textSize = g.MeasureString(text, font);

                        // 文本位置计算，稍微向内缩进
                        float textX = centerX + (float)((radius - 25) * Math.Cos(angleRad)) - textSize.Width / 2;
                        float textY = centerY + (float)((radius - 25) * Math.Sin(angleRad)) - textSize.Height / 2;
                        g.DrawString(text, font, scaleBrush, textX, textY);
                    }

                    // 绘制次刻度线
                    for (float i = _minimum; i <= _maximum; i += 0.2f) // 每隔0.2个单位一个次刻度
                    {
                        if (Math.Abs(i % 1.0f) < 0.01f) continue; // 跳过主刻度
                        if (i > _maximum) break; // 避免超出最大值

                        float angle = startAngle + (i / (_maximum - _minimum)) * sweepAngle;
                        float angleRad = (float)(angle * Math.PI / 180);

                        // 次刻度线起点
                        float x1 = centerX + (float)((radius - 5) * Math.Cos(angleRad));
                        float y1 = centerY + (float)((radius - 5) * Math.Cos(angleRad));

                        // 次刻度线终点
                        float x2 = centerX + (float)(radius * Math.Cos(angleRad));
                        float y2 = centerY + (float)(radius * Math.Sin(angleRad));
                        g.DrawLine(scalePen, x1, y1, x2, y2);
                    }

                    // 绘制单位文本
                    SizeF unitTextSize = g.MeasureString(UnitText, unitFont);
                    g.DrawString(UnitText, unitFont, scaleBrush,
                                 centerX - unitTextSize.Width / 2,
                                 centerY + radius / 4 - unitTextSize.Height / 2);
                }

                // 3. 绘制中心圆帽
                int centerCapRadius = 15;
                RectangleF centerCapRect = new RectangleF(centerX - centerCapRadius, centerY - centerCapRadius, centerCapRadius * 2, centerCapRadius * 2);
                g.FillEllipse(new SolidBrush(Color.DimGray), centerCapRect);
                g.DrawEllipse(Pens.DarkGray, centerCapRect);

                // 4. 绘制指针
                using (var pointerPen = new Pen(this.PointerColor, 3))
                {
                    pointerPen.StartCap = LineCap.Flat;
                    pointerPen.EndCap = LineCap.ArrowAnchor; // 指针末端为箭头

                    float totalRange = _maximum - _minimum;
                    if (totalRange <= 0) return;

                    float valueRatio = (_value - _minimum) / totalRange;
                    float currentAngle = 225 + (valueRatio * 270); // 270度是总的扫描角度

                    // 将角度转换为弧度
                    float angleRad = (float)(currentAngle * Math.PI / 180);

                    // 指针起点 (稍微偏离中心，给中心圆帽留空间)
                    float pointerStartX = centerX + (float)(centerCapRadius * 0.5 * Math.Cos(angleRad + Math.PI)); // 反方向起点
                    float pointerStartY = centerY + (float)(centerCapRadius * 0.5 * Math.Sin(angleRad + Math.PI));

                    // 指针终点 (距离边缘一定距离)
                    float pointerEndX = centerX + (float)((radius - 5) * Math.Cos(angleRad));
                    float pointerEndY = centerY + (float)((radius - 5) * Math.Sin(angleRad));

                    g.DrawLine(pointerPen, pointerStartX, pointerStartY, pointerEndX, pointerEndY);
                }
            }
        }
    }